/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package asis;

import asis.ASISSaveFile.GUISettings;
import asis.gui.*;
import asis.ini.INI;
import asis.ini.TweakIniList;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import lev.gui.LSaveFile;
import skyproc.*;
import skyproc.gui.SPMainMenuPanel;
import skyproc.gui.SPProgressBarPlug;
import skyproc.gui.SUM;
import skyproc.gui.SUMGUI;

/**
 *
 * @author pc tech
 */
public class ASIS implements SUM {

    public static String ASISlanguage;
    static ArrayList<String> modExclusions = new ArrayList<>(0);
    Map settingsMap;
    public static boolean debug;
    //Stores the memory for the program, read from the ini and then restarts the program.
    public static int memory;
    //Stores the save file to store user settings on the disk.
    public static LSaveFile save = new ASISSaveFile();
    //Colors used in the GUI.
    static public Color blue = new Color(0, 147, 196);
    static public Color green = new Color(67, 162, 10);
    static public Color darkGreen = new Color(61, 128, 21);
    static public Color orange = new Color(247, 163, 52);
    static public Color yellow = new Color(255, 204, 26);
    static public Color lightGray = new Color(190, 190, 190);
    static public Color darkGray = new Color(110, 110, 110);
    //Fonts used in the GUI.
    static public Font settingsFont = new Font("Serif", Font.BOLD, 14);
    static public Font settingsFontSmall = new Font("Serif", Font.BOLD, 12);
    //The Main Menu panel for the background.
    static public SPMainMenuPanel settingsMenu;
    //All the individual panels for editing settings.
    //static public Settings settingsPanel;
    static public SettingsIncreasedSpawns settingsIncreasedSpawns;
    static public SettingsSpawnRandomizer settingsSpawnRandomizer;
    static public SettingsNPCPotions settingsNPCPotions;
    static public SettingsAutomaticPerks settingsAutomaticPerks;
    static public SettingsAutomaticSpells settingsAutomaticSpells;
    static public SettingsCustomizedAI settingsCustomizedAI;
    static public SettingsCustomizedGMSTs settingsCustomizedGMSTs;
    // Version
    public static String version = "1.33 RC";
    //Number of progress steps.
    final static int numSteps = 30;
    static int steps = 0;
    //Tweak INI's
    public TweakIniList tweakInis;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException, Exception {

        ArrayList<String> arguments = new ArrayList<>(Arrays.asList(args));
        ASIS main = new ASIS();
        main.processINI();

        if (!arguments.contains("-nonew") && memory != 0) {

            NiftyFunc.allocateMoreMemory("100m", memory + "m", "ASIS.jar", "-nonew");
        }
        SPGlobal.setGlobalPatch(main.getExportPatch());

        save.init();
        SUMGUI.open(new ASIS());
    }

    @Override
    public void runChangesToPatch() throws Exception {
        SPGlobal.loggingSync(true);
        SPGlobal.logging(true);
        SPGlobal.getGlobalPatch().setFlag(Mod.Mod_Flags.STRING_TABLED, true);

        SPProgressBarPlug.setMax(numSteps);
        SPProgressBarPlug.setStatus(steps++, numSteps, "Initializing ASIS");

        asis();
    }

    public void asis() {
        //SPProgressBarPlug.setStatus("Starting Import Process");
        //SPGUI.progress.pause(true);

        if (asis.ASIS.debug) {
            setSkyProcGlobalDebug();
        }

        //Mod patch = runModSetup();

        getTweakIniSetup();
        
        runClasses();

        SPProgressBarPlug.incrementBar();
    }

    public ArrayList<String> getModExclusions() {
        return modExclusions;
    }

    public TweakIniList getTweakIni() {
        return tweakInis;
    }

    private void setSkyProcGlobalDebug() {
        SPGlobal.createGlobalLog();
        SPGlobal.debugModMerge = true;
    }

    private void runClasses() {
        if (ASIS.save.getBool(GUISettings.AUTOMATICSPELLS_ON)) {
            SPProgressBarPlug.setStatus("Processing Automatic Spells");
            AutomaticSpells AutomaticSpells = new AutomaticSpells();
            AutomaticSpells.addSpells(this);
        }
        SPProgressBarPlug.incrementBar();
        
        if (ASIS.save.getBool(GUISettings.INCREASEDSPAWNS_ON)) {
            SPProgressBarPlug.setStatus("Processing Increased Spawns");
            IncreasedSpawns IncreasedSpawns = new IncreasedSpawns();
            IncreasedSpawns.addSpawns(this);
        }
        SPProgressBarPlug.incrementBar();
        
        if (ASIS.save.getBool(GUISettings.NPCPOTIONS_ON)) {
            SPProgressBarPlug.setStatus("Processing NPCPotions");
            NPCPotions NPCPotions = new NPCPotions();
            NPCPotions.addPotions(this);
        }
        SPProgressBarPlug.incrementBar();
        
        if (ASIS.save.getBool(GUISettings.CUSTOMIZEDAI_ON)) {
            SPProgressBarPlug.setStatus("Processing Customized AI");
            CustomizedAI myCustomizedAI = new CustomizedAI();
            myCustomizedAI.runCustomizedAI(this);
        }
        SPProgressBarPlug.incrementBar();

        if (ASIS.save.getBool(GUISettings.AUTOMATICPERKS_ON)) {
            SPProgressBarPlug.setStatus("Processing Automatic Perks");
            AutomaticPerks autoPerks = new AutomaticPerks();
            autoPerks.addPerks(this);
        }
        SPProgressBarPlug.incrementBar();

        if (ASIS.save.getBool(GUISettings.SPAWNRANDOMIZER_ON)) {
            SPProgressBarPlug.setStatus("Processing Spawn Randomizer");
            SpawnRandomizer randomSpawns = new SpawnRandomizer();
            randomSpawns.addRandomSpawns(this);
        }
        SPProgressBarPlug.incrementBar();

        if (ASIS.save.getBool(GUISettings.CUSTOMIZEDGMSTS_ON)) {
            SPProgressBarPlug.setStatus("Processing Customized GMSTs");
            customizedGMSTs customGMSTs = new customizedGMSTs();
            customGMSTs.runCustomizedGMSTs(this);
        }
        SPProgressBarPlug.incrementBar();
    }

    private void getTweakIniSetup() {
        try {
            tweakInis = new TweakIniList();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "There was an error with Tweak Inis.  Please contact the author.");
        }
    }

    public String getLanguage() {
        return ASISlanguage;
    }

    @Override
    public String getName() {
        return "ASIS";
    }

    @Override
    public GRUP_TYPE[] importRequests() {
        return new GRUP_TYPE[] {GRUP_TYPE.NPC_, GRUP_TYPE.SPEL, GRUP_TYPE.PERK, GRUP_TYPE.LVLI, GRUP_TYPE.FACT };
    }

    @Override
    public boolean importAtStart() {
        return false;
    }

    @Override
    public boolean hasStandardMenu() {
        return true;
    }

    @Override
    public SPMainMenuPanel getStandardMenu() {
        settingsMenu = new SPMainMenuPanel(blue);
        settingsMenu.setVersion(version, new Point(80, 88));
        SUMGUI.helpPanel.setHeaderFont(new Font("Serif", Font.BOLD, 18));

        settingsIncreasedSpawns = new SettingsIncreasedSpawns(settingsMenu);
        settingsMenu.addMenu(settingsIncreasedSpawns, true, save, GUISettings.INCREASEDSPAWNS_ON);

        settingsAutomaticPerks = new SettingsAutomaticPerks(settingsMenu);
        settingsMenu.addMenu(settingsAutomaticPerks, true, save, GUISettings.AUTOMATICPERKS_ON);

        settingsAutomaticSpells = new SettingsAutomaticSpells(settingsMenu);
        settingsMenu.addMenu(settingsAutomaticSpells, true, save, GUISettings.AUTOMATICSPELLS_ON);

        settingsCustomizedAI = new SettingsCustomizedAI(settingsMenu);
        settingsMenu.addMenu(settingsCustomizedAI, true, save, GUISettings.CUSTOMIZEDAI_ON);

        settingsCustomizedGMSTs = new SettingsCustomizedGMSTs(settingsMenu);
        settingsMenu.addMenu(settingsCustomizedGMSTs, true, save, GUISettings.CUSTOMIZEDGMSTS_ON);

        settingsNPCPotions = new SettingsNPCPotions(settingsMenu);
        settingsMenu.addMenu(settingsNPCPotions, true, save, GUISettings.NPCPOTIONS_ON);

        settingsSpawnRandomizer = new SettingsSpawnRandomizer(settingsMenu);
        settingsMenu.addMenu(settingsSpawnRandomizer, true, save, GUISettings.SPAWNRANDOMIZER_ON);

        return settingsMenu;
    }

    @Override
    public boolean hasCustomMenu() {
        return false;
    }

    @Override
    public boolean hasLogo() {
        return false;
    }

    @Override
    public URL getLogo() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean hasSave() {
        return true;
    }

    @Override
    public LSaveFile getSave() {
        return save;
    }

    @Override
    public String getVersion() {
        return version;
    }

    @Override
    public ModListing getListing() {
        return new ModListing("ASIS", false);
    }

    @Override
    public Mod getExportPatch() {
        Mod patch = new Mod(getListing());
        patch.setFlag(Mod.Mod_Flags.STRING_TABLED, false);
        patch.setAuthor("Pluto and Dres Croffgrin");
        return patch;
    }

    @Override
    public Color getHeaderColor() {
        return blue;
    }

    @Override
    public GRUP_TYPE[] dangerousRecordReport() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public JFrame openCustomMenu() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean needsPatching() {
        return true;
    }

    @Override
    public void onStart() throws Exception {
        processINI();
        SPGlobal.language = ASISlanguage;
    }

    @Override
    public void onExit(boolean patchWasGenerated) throws Exception {
        SPGlobal.logMain("EXIT", "Closing ASIS.");
    }

    enum INItypes {

        LANGUAGE,
        MODEXCLUSIONS
    }

    private void processINI() throws FileNotFoundException, IOException {
        SPProgressBarPlug.setStatus("ASIS: Processing INI");
        SPProgressBarPlug.incrementBar();
        //Sets up the file reader for the ini file.
        INI ini = null;

        //Sets up the file reader for the ini file.
        try {
            ini = new INI("ASIS.ini");
        } catch (IOException ex) {
            Logger.getLogger(NPCPotions.class.getName()).log(Level.SEVERE, null, ex);
        }

        Collection<INI.IniSectionHead> sections = getSectionList();

        ini.addSection(sections);

        try {
            ini.readData();
        } catch (IOException ex) {
            Logger.getLogger(NPCPotions.class.getName()).log(Level.SEVERE, null, ex);
        }

        initializeLists(ini);
    }

    private Collection<INI.IniSectionHead> getSectionList() {
        Collection<INI.IniSectionHead> sectionList = new ArrayList<>();

        for (IniSection currentSection : IniSection.values()) {
            sectionList.add(new INI.IniSectionHead(currentSection.getName(), currentSection.getFormat()));
        }

        return sectionList;
    }

    private void initializeLists(INI ini) {
        try {
            ASISlanguage = ((ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.LANGUAGE.getName(),
                    IniSection.LANGUAGE.getFormat()))).get(0).toString();
        } catch (Exception e) {
            ASISlanguage = "English";
        }
        try {
            modExclusions = (ArrayList) ini.getCollection(new INI.IniSectionHead(IniSection.MODEXCLUSIONS.getName(),
                    IniSection.MODEXCLUSIONS.getFormat()));
        } catch (Exception e) {
        }

        try {
            settingsMap = ini.getMap(new INI.IniSectionHead(IniSection.SETTINGS.getName(),
                    IniSection.SETTINGS.getFormat()));
        } catch (Exception e) {
        }

        try {
            debug = Boolean.parseBoolean((String) settingsMap.get("debug"));
        } catch (Exception e) {
        }
        try {
            memory = Integer.parseInt((String) (settingsMap.get("memory")));
        } catch (Exception e) {
        }
    }

    private enum IniSection {

        LANGUAGE(INI.IniDataFormat.VALUE, "LANGUAGE"),
        SETTINGS(INI.IniDataFormat.KEY_VALUE, "SETTINGS"),
        MODEXCLUSIONS(INI.IniDataFormat.VALUE, "MODEXCLUSIONS");
        private INI.IniDataFormat format;
        private String name;

        IniSection(INI.IniDataFormat format, String name) {
            this.format = format;
            this.name = name;
        }

        String getName() {
            return name;
        }

        INI.IniDataFormat getFormat() {
            return format;
        }
    }
}
